﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Song.Common.Tools
{
    /// <summary>
    /// 泛型扩展方法
    /// </summary>
    public static class GenericExtensions
    {
        public static bool IsBetween<T>(this T t, T lowerBound, T upperBound, bool includeLowerBound = false, bool includeUpperBound = false)
        where T : class, IComparable<T>
        {
            if (t == null) throw new ArgumentNullException("t");

            var lowerCompareResult = t.CompareTo(lowerBound);
            var upperCompareResult = t.CompareTo(upperBound);

            return (includeLowerBound && lowerCompareResult == 0) ||
                (includeUpperBound && upperCompareResult == 0) ||
                (lowerCompareResult > 0 && upperCompareResult < 0);
        }

        public static bool In<T>(this T t, params T[] c)
        {
            return c.Any(i => i.Equals(t));
        }
        //改进的Aggerate扩展（示例代码，实际使用请添加空值检查）
        public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, int, TSource> func)
        {
            int index = 0;
            using (IEnumerator<TSource> enumerator = source.GetEnumerator())
            {
                enumerator.MoveNext();
                index++;
                TSource current = enumerator.Current;
                while (enumerator.MoveNext())
                    current = func(current, enumerator.Current, index++);
                return current;
            }
        }

        public static T If<T>(this T t, Predicate<T> predicate, params Action<T>[] actions) where T : class
        {
            if (t == null) throw new ArgumentNullException();
            if (predicate(t))
            {
                foreach (var action in actions)
                    action(t);
            }
            return t;
        }
        public static void While<T>(this T t, Predicate<T> predicate, params Action<T>[] actions) where T : class
        {
            while (predicate(t))
            {
                foreach (var action in actions)
                    action(t);
            }
        }

        /// <summary>
        /// 改进后链式编程扩展
        /// </summary>
        /// <typeparam name="T">输入参数类型</typeparam>
        /// <param name="t">输入参数</param>
        /// <param name="func">委托</param>
        /// <returns>返回值</returns>
        public static T Do<T>(this T t, Func<T, T> func)
        {
            return func(t);
        }
    }
}
